package com.chen.function_demo.chapter3;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Stream;

/**
 * 第三章第七节
 *
 * @author 陈哲<p>
 * ================================<p>
 * Date: 2025/5/12<p>
 * Time: 11:51<p>
 * ================================
 */
public class Section7 {
    /*
        并行流：
        如何获取并行流，即在中间操作之前，调用parallel方法
     */
    public static void main(String[] args) {
        // 模拟一个流
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        // 并行流
        integerStream
                .parallel() // 并行流
                .filter(item -> item % 2 == 0) // 中间操作
                .map(item -> item * 2) //  中间操作
                .forEach(System.out::println); // 终止操作
        System.out.println("-----------------------------------------");
        /*
            通过collect作为切入点，研究并行流如何工作的。通过自定义收集器一步步深入
            一个完整的收集器需要4段逻辑、1个特征
            1、4段逻辑：
            （1）如何创建容器
            （2）如何向容器添加元素
            （3）如何合并两个容器的数据
            （4）收尾
            2、特性（可选的有三种）：特性可以选0到3个
            （1）是否要支持收尾（默认收尾）、（2）是否需要保证顺序（默认保证）、（3）收集的容器是否支持并发（默认不支持）；
         */
        // 创建流
        Stream<Integer> integerStream2 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        List<Integer> integerList = integerStream2
                .parallel() // 并行流
                .collect(Collector.of(  // Collector.of() 是创建收集器的方法
                        () -> new ArrayList<Integer>(),  // 1、如何创建容器 supplier 以list为例
                        ArrayList::add,   //2、如何向容器添加元素 BiCustomer(容器，元素) -> 添加方法
                        (list1, list2) -> {
                            list1.addAll(list2);
                            return list1;
                        },   //3、如何合并两个容器的数据
                        list -> list  //4、收尾 function
                        // 特性不写，默认不支持并发、会调用收尾逻辑、保证收集顺序
                ));
        integerList.forEach(System.out::println);
        System.out.println("-----------------------------------------");
        // 创建流
        Stream<Integer> integerStream3 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        List<Integer> integerList2 = integerStream3
                .parallel() // 并行流
                .collect(Collector.of(  // Collector.of() 是创建收集器的方法
                        () -> Collections.synchronizedList(new ArrayList<Integer>()),  // 1、如何创建容器 supplier 以list为例
                        List::add, //2、如何向容器添加元素 BiCustomer(容器，元素) -> 添加方法
                        (list1, list2) -> {
                            list1.addAll(list2);
                            return list1;
                        },   //3、如何合并两个容器的数据
                        list -> list,  //4、收尾 function
                        // 特性
                        Collector.Characteristics.IDENTITY_FINISH,  // 不执行收尾操作
                        Collector.Characteristics.UNORDERED,  // 不保证顺序
                        Collector.Characteristics.CONCURRENT  // 容器支持并发，比如选了这个之后，就不能用ArrayList了，因为ArrayList线程不安全
                        // Collector.Characteristics.UNORDERED + Collector.Characteristics.CONCURRENT + 线程安全容器

                ));
        integerList2.forEach(System.out::println);

    }
}
